package com.exes;


import com.alibaba.fastjson2.JSON;
import com.db.CacheDb;
import com.db.ExcelUtils;
import com.mapper.DocumentInfoMapper;
import com.model.DocumentInfo;
import com.vo.Condition;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.internal.http.HttpHeaders;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class RequestExecutor {
//    private String entryUrl = "https://kns.cnki.net/KNS8/Brief/GetGridTableHtml";
//
//    private String querySql = "0645419CC2F0B23BC604FFC82ADF67C6E920108EDAD48468E8156BA693E89F481391D6F5096D7FFF3585B29E8209A884EFDF8EF1B43B4C7232E120D4832CCC8979F171B4C268EE675FFB969E7C6AF23B4B63CE6436EE93F3973DCB2E4950C92CBCE188BEB6A4E9E17C3978AE8787ED6BB56445D70910E6E32D9A03F3928F9AD8AADE2A90A8F00E2B29BD6E5A0BE025E88D8E778EC97D42EF1CF47C35B8A9D5473493D11B406E77A4FF28F5B34B8028FE85F57606D7A3FED75B27901EEF587583EBD4B63AC0E07735BE77F216B50090DEE5ABB766456B996D37EB8BDACA3A67E8126F111CF9D15B351A094210DB6B4638A21065F03B6F0B73BB4625BBECE66F8197909739D8FB4EB756DEF71864177DFA3CB468CFA6E8ABF7924234DED6B0DFD49D9269CBA4A2BF4075D517A61D094225D70C1B4C137DB9614758A5E097376F5F3E55A7063A4B7E437436D13FF3CC8FB435E131FFCD16FC30DD997098B4FC997D995E767E2712175BC05B960D3FEB5CAF12A13BD1CE3530AD72FC4DB93206996E216BC5DC294960A0CA05E986848E1E64FFC5A52BFCB41A97840A708E397F11EFF261E08F3A34094061AE8E8F819AF6A17A9E2176C3893C6DD3E3C06864C91989BDEF9790A38FAF2524B17743B30EBA4ADD550BF985F9C3097A608C697283CE37F8CB78BDC9EAA4874C3485E6F931B016EC41BFBC0EF91B2AD7E1B424E1DFB8FC8771DEA2458C5A7A4C9BF0192C101FD8EDDEE1BACB44C3E478361EF0D1B70FAD56BCF6870A6044D3A226611B9C1A43C6F9F7C021C98E0D5F778D72C87183F026071A730B8BB4FABF9F68FEC783AB1E6E79218B5D87FD1BB541817FB4F3C21DC849A803CB8A620A2EE00475BAF2CE6556638B7A949B446F39A1076DA15764A777BA6239447CB91F4CF513325366E167D268DDB75F288B5C13415CE62F5C431181C044A28CA502FF14439E5C6F63D419CB6DE1360DB01593FE765459299E442EE24917C199AB5178F38461F8C4EBBC95344C5F2AB60F379813A87E2E3AFE3021198B8222CEAB870D9A353786079961184D63977917C7DF8FE6AFBBC795A832BDD454D6E3CD22C3FF7A58808923DD6F464C12A9A88FBFD0C71458AB0E4C1D566315181A9578ECE93670E5CAF13CF2553F68E64726C131F4A48B42A9E7F09EFEBA51D1FDA6BA0ECA0B02B951ECC04548F1D4D08DB69D0EFDCE6793537BB8E59DC442631A9CDBA13878D7493AADA0CD868C1C1C3A6A6FA17C4109205A83F9C0C43E0D2551D0A8592EA99D20D4B78B4EEEE2D53A543701F620C7D6FF46E800B0CEF9B3D23ACD62C7CBEA25FC8BD74D5A0E5C86B9CF3FCACBDBE585AFF85F9689CBF5BCBD267C580361D5B93AA9BD5A1BB6122BB87C04AE227211FE675A4650814F2285261E5641683D65E0454E2597F6025BB4AA1A044D7B97F57394EA5EC878B80FC0A82F12E2D3D9E1BCB062A7ABB290F02116BDED95761A67CE2FDDE42BDDDF34F22E49A0406D724FEBC86B93F80BB52A8D34B8D2B24288ECBC3F90CCB1EF36085E77F1E2AE0AB411FE60A033E704A21469EA5CE4BB8AF6B1C1F1C5F1F084472D57F458CC39F0B2FE583D0795159E9E38BD1102F5D96DB0F828B66F41A702BB0AE59E40CF53BE7F6342EF208434CFFABF845AFD771B288D484BB79952159E6EA27658A6B6230557AF16E86C4AFDF973DBD5A3A2B979AD9037441409D22A954DC50CBCEA8EA5AC500C4BC8282DCE2626BD2B2CB4B1E33B2E1F92533F7F04C48D061907DBCE3E21FF0A77F09C1AE33E769962CD1EDE6B688590D569409EE9EEC4DF1074DCC97C43B0EDAF1C38B5B2784ABC803D9B3B4FC35F46CB1E275E7F83036FC6AFF2E624D4D2E6AE1C2D4CE3FF219FA90A935957E0DE1A386E4AAB5C9F9D1CECA909F5698BFA86C57B6A73D3C0F9FDB94128B7BB9FDD19D57E4C2C2F4127A1F127A96ABF248B26D8B6EF12A1EA97D064564D33D46E5CA71F53FA121A7E5C91ED2B08BE64A0E3D22BE26FC251C0BF4CF21674DE19AF410E3EDFBD9A4BBEA6C709A1E42B5C17E1EE7AA33EFB0F375BF0858D49210A71662313FA5B8E04E508A5E9425D49C3C5D12CB8DCADBF8A148BFA042BBB0218AAC403AAB9CECC45FD33CEC6797FC984BF91FF638AF6E1F09546F595CFC779D2D867282C63B78DC6A6ED3C1C3887462C84AC07C756C5A8D8A8B2EFD39C28A68D47091A3312461BC20085636F4B41F22D5B46861F3E557777CDCFDFE6CAB8ABECFECA3634D779C0F21185772CA46EA1C0B1E0191F02F11A2B10372550A8B839D8C819F77A67512CA57D16DBA687D1BB77271E375C6DD3432C804B0A707D0DF7D72108E3190885E95DE0F0F118A904C80D606BB82C582FF3E3D836AED573EA426D382FF3D0C83B51E0E63B863FC20F67D2C68C14558E2EEDED6B71B615A74152632E0E1A4BFC01F083BEEA6E702D1650038B1826D1970F88507FB5E5C07A18F3BD94177B73C5C9E960EE73ED66B353BB65245EABB7D552BA6F27425B703A081479862CF0C6A2102A796F0B93F072D362F8CE04AB334C4342186C69F946794EE812FFC903D270DF98BCEAF98F8C4D685BB25DD848FBDE28BE6A5DB4564BF4D9115620B5BA45E1A86A44A0F4A1D1839184E8E952AB38050D6C2A5378577AB09FA6A5167AA498C61F04853CCA741B2A360E4EA67F8F67E4739DFB9DF144C9D44CBAFEA30AD7B764F276F570674A2333F36EB6C9051026EA82DE60C00EFB5DF9661474D1A9DDD4137C8E7DC9E1B9C4D4E6D9091E5764AECB618E94F85A503FBACE93CAB29A06953832D09B0209A14A166A74F1CD4897AE8859A481A4DBFAD581995A658F3760823F3D9B538DD0053554A723CBD58B946830D2FA2B6D7B488523EEBCC212063F740F5127D3FFE63AA9C5D7C62255D6DBB723793A8820602C283EBC2C92B8E27C02029F21B390253C6DB1351C957B7659BA0A76C89553CFD756B5198FB516331D4CF6F4491084DB061E6032C5A338DEF833F6C35D1A1B9B555CD1AC61A8E6AD4D59B08CBFFB16DAA2BAF98D1ABD4ECBBEF20B8AE5EA38D285D24CF6AB8265B69DF4ED9DDB3F68A20E73DB8364701311959375852CB434300F382F23653894913593BE87AF79DF287C4F4994AF82F69F3CE0B531356A006B66B89F54425B5FC23C77C653464472AE0D59";
//    private String queryJson = "{\"Platform\":\"\",\"DBCode\":\"CFLS\",\"KuaKuCode\":\"CJFQ,CCND,CIPD,CDMD,BDZK,CISD,SNAD,CCJD,GXDB_SECTION,CJFN,CCVD\",\"QNode\":{\"QGroup\":[{\"Key\":\"Subject\",\"Title\":\"\",\"Logic\":1,\"Items\":[{\"Title\":\"主题\",\"Name\":\"SU\",\"Value\":\"关键词\",\"Operate\":\"%=\",\"BlurType\":\"\"}],\"ChildItems\":[]}]},\"CodeLang\":\"ch\"}";
//    public static final MediaType JSONType = MediaType.get("application/json; charset=utf-8");

//    String path = "E:\\tmp\\test.xlsx";
//    public String host = "https://kns.cnki.net";

    private ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 20, 30, TimeUnit.SECONDS, new LinkedBlockingDeque<>());

    public static CountDownLatch countDownLatch = new CountDownLatch(0);

    @Autowired
    DocumentInfoMapper documentInfoMapper;

//    private Condition buildCondition(String keyword, Integer page){
//        String newQueryJson = queryJson.replace("关键词", keyword);
//        return Condition.builder()
//                .IsSearch("false")
//                .QueryJson(newQueryJson)
//                .SearchSql(querySql)
//                .PageName("defaultresult")
//                .HandlerId("2")
//                .DBCode("CFLS")
//                .KuaKuCodes("CJFQ,CCND,CIPD,CDMD,BDZK,CISD,SNAD,CCJD,GXDB_SECTION,CJFN,CCVD")
//                .CurPage(page.toString())
//                .RecordsCntPerPage("50")
//                .CurDisplayMode("listmode")
//                .CurrSortField("PT")
//                .CurrSortFieldType("desc")
//                .IsSearch("false")
//                .IsSentenceSearch("false")
//                .Subject("")
//                .build();
//    }

    private String keywords[] = {"计算机", "艺术", "医学", "历史学", "经济学", "法学", "教育学"};

    public void run() throws IOException, InterruptedException {

        String keyWord = keywords[7];
//        for(int year = 2023; year >= 2018; year --) {
//            Integer startPage = 1;
//            Integer num = 120;
//            countDownLatch = new CountDownLatch(num - startPage + 1);
//            for (int i = startPage; i <= num; i++) {
//                threadPool.submit(new RequestRunner(keyWord, i, year, year, documentInfoMapper));
//            }
//            countDownLatch.await();
//        }

        Calendar instance = Calendar.getInstance();
        instance.setTime(new Date());
        int nowYear = instance.get(Calendar.YEAR);
        int nowMonth = instance.get(Calendar.MONTH) + 1;
        System.out.println(nowYear + "; " + nowMonth);
        for(int year = 2023; year >= 2020; year--){
            int maxMonth = 12;
            if(year == nowYear){
                maxMonth = nowMonth;
            }
            int maxNum = 120;
            countDownLatch = new CountDownLatch(maxMonth * maxNum);
            for(int month = 1; month <= maxMonth; month ++){
                String startTime = year + "-"+ month + "-1";
                String endTime = year + "-" + month + "-31";
                String searchSql = CnkiSearchBuilder.getSearchSql(keyWord, startTime, endTime);
                for(int page = 1; page <= 120; page ++){
                    System.out.println("submit: " + keyWord + "; " + page + "; " + startTime + "; " + endTime);
                    threadPool.submit(new RequestRunner(keyWord, page, startTime, endTime, documentInfoMapper, searchSql));
                }
            }
            countDownLatch.await();
        }

    }

//    public void start(String keyWord, int page) throws IOException {
//        OkHttpClient okHttpClient = new OkHttpClient();
//        RequestBody body = RequestBody.create(JSONType, JSON.toJSONString(buildCondition(keyWord, page)));
//        Request request = new Request.Builder()
//                .url(entryUrl)
//                .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70'")
//                .addHeader("Referer", "https://kns.cnki.net/KNS8/AdvSearch?dbcode=CJFQ")
//                .post(body)
//                .build();
//        Response response = okHttpClient.newCall(request).execute();
//        String responseHtml = response.body().string();
//
//        Document doc = Jsoup.parse(responseHtml);
//        Elements elements = doc.select(".result-table-list tbody tr");
//        elements.forEach(element->{
//            Elements tds = element.select("td");
//            DocumentInfo documentInfo = DocumentInfo.builder()
//                    .title(tds.get(1).select("a").get(0).text())
//                    .detailLink(host + tds.get(1).select("a").get(0).attr("href"))
//                    .author(tds.get(2).text())
//                    .source(tds.get(3).select("a").get(0).text())
//                    .releaseTime(tds.get(4).text())
//                    .database(tds.get(5).text())
//                    .downloadCount(Integer.parseInt(tds.get(7).text()))
//                    .build();
//            CacheDb.data.add(documentInfo);
//        });
//    }
}
